home *** CD-ROM | disk | FTP | other *** search
- program envcalc;
-
- {$V-}
-
- uses objects, {strg,uwstring,} uwcalc;
-
- {}
-
- procedure strupr(var s:string);
- var
- x:byte;
- begin
- for x:=1 to length(s) do s[x]:=upcase(s[x])
- end;
-
- procedure ssplit(entry:string; sep:char; var head,tail:string);
- var
- v:byte;
- begin
- head:=entry; tail:='';
- v:=pos(sep,entry);
- if (v=0) then EXIT;
- head:=copy(entry,1,v-1);
- tail:=copy(entry,v+1,255)
- end;
-
- function dictpos(var dict:string; word:string; wsep:char):byte;
- var
- v,x,z:byte;
- begin
- dictpos:=0;
- z:=pos(word+wsep,dict);
- if (z=0) then exit;
- inc(z,length(word));
- v:=0; x:=0;
- repeat
- inc(v);
- if (dict[v]=wsep) then inc(x)
- until (v=z);
- dictpos:=x
- end;
-
- {}
-
- const
- ecsep='=';
- eclft='[';
- ecrgt=']';
- eclen=127;
-
- type
- tenvstr=string[127];
- penvstr=^tenvstr;
-
- type
- penvctn=^tenvctn;
- tenvctn=object(tcollection)
- procedure freeitem(item:pointer);virtual;
-
- function fndtoken(atoken:tenvstr):pointer;
- procedure getvalue(atoken:tenvstr; var value:tenvstr);
- procedure setvalue(atoken:tenvstr; var value:tenvstr);
- procedure getentry(index:integer; var token,value:tenvstr);
- procedure echovar(var atoken:tenvstr);
- procedure echostr(var acmdln:string);
- end;
-
- procedure tenvctn.freeitem;
- begin
- disposestr(item)
- end;
-
- function tenvctn.fndtoken;
- function matches(item:pointer):boolean;far;
- begin
- matches:=(copy(pstring(item)^,1,pos(ecsep,pstring(item)^)-1)=atoken)
- end;
- begin
- strupr(atoken);
- fndtoken:=firstthat(@matches)
- end;
-
- procedure tenvctn.getvalue;
- var
- p:pointer;
- begin
- p:=fndtoken(atoken);
- if (p=nil)
- then value:=''
- else value:=copy(pstring(p)^,pos(ecsep,pstring(p)^)+1,eclen)
- end;
-
- procedure tenvctn.setvalue;
- var
- p:pointer;
- begin
- strupr(atoken);
-
- p:=fndtoken(atoken);
- if (p<>nil) then free(p);
-
- if (value='') then EXIT;
-
- insert(newstr(atoken+ecsep+value))
- end;
-
- procedure tenvctn.getentry;
- {-Index -MUST- be in the range 0..pred(count).}
- begin
- ssplit(pstring(at(index))^,ecsep,token,value)
- end;
-
- procedure tenvctn.echovar;
- {-Returns value if atoken defined.}
- { Otherwise atoken is not altered.}
- var
- value:tenvstr;
- begin
- value:='';
- getvalue(atoken,value);
- if (value<>'') then atoken:=value
- end;
-
- procedure tenvctn.echostr;
- {-Replaces any [token]s with their values.}
- var
- v,x,z:byte;
- value:tenvstr;
- label
- scan;
- begin
- v:=0;
- scan:
- z:=v;
- v:=pos(eclft,copy(acmdln,z+1,255));
- if (v=0) then EXIT;
-
- x:=pos(ecrgt,copy(acmdln,z+v+1,255));
- if (x=0) then EXIT;
- getvalue(copy(acmdln,z+v+1,x-1),value);
-
- if (value='') {1234[6789]1234[6789]}
- then v:=z+v+x
- else begin
- system.delete(acmdln,z+v,x+1);
- {strins(acmdln,value,z+v,255);}
- system.insert(value,acmdln,z+v);
- v:=z+v+length(value)
- end;
- goto scan
- end;
-
- {}
-
- var
- env:tenvctn;
- s,token,value:string;
- r:real;
- x:byte;
- const
- cmset=1;
- cmecho=2;
- cmcalc=3;
- cmlet=4;
- vocab:string='SET,ECHO,CALC,LET,';
-
- procedure reply(atoken:tenvstr);
- begin
- env.getvalue(atoken,value);
- strupr(atoken);
- writeln('> ',atoken,ecsep,value)
- end;
-
- BEGIN
- writeln('Available commands include SET ECHO CALC and LET.');
- env.init(16,16);
- with env do repeat
- write('? '); readln(s);
-
- ssplit(s,' ',token,value);
- strupr(token);
-
- case dictpos(vocab,token,',') of
- cmset:
- begin
- if (value<>'')
- then begin
- ssplit(value,ecsep,token,value);
- setvalue(token,value);
- if (value<>'') then reply(token)
- end
- else if (count>0)
- then for x:=0 to pred(count) do
- writeln('> ',pstring(at(x))^)
- end;
- cmecho:
- begin
- echostr(value); writeln(value)
- end;
- cmcalc:
- begin
- echostr(value); stdsub(value); value:=value+csequal;
- if calcstr(r,value)
- then writeln('> ',value)
- else writeln('! ',cserrst)
- end;
- cmlet:
- begin
- ssplit(value,ecsep,token,value);
- echostr(value); stdsub(value); value:=value+csequal;
- if calcstr(r,value)
- then setvalue(token,value)
- else setvalue(token,cserrst);
- reply(token)
- end
- end
-
- until (s='');
- env.done
- END.
-